﻿using DevExpress.XtraBars.Docking;
using DevExpress.XtraNavBar;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Forms;

namespace CXW.Core.Sharp.Gui
{
    class DockManagerExt : DockManager
    {
        Dictionary<string, DockPanel> _dockPanelExt = new Dictionary<string, DockPanel>() { { "Left", null }, { "Right", null }, { "Top", null }, { "Bottom", null } };
        List<DockPanel> _dockPanelAll = new List<DockPanel>();
        List<DockPanel> _dockPanelLeft = new List<DockPanel>();
        List<DockPanel> _dockPanelRight = new List<DockPanel>();
        List<DockPanel> _dockPanelTop = new List<DockPanel>();
        List<DockPanel> _dockPanelBottom = new List<DockPanel>();
        /// <summary>返回全部停靠方向的 ICollection&lt;DockPanel&gt; 只读集合</summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]
        public ReadOnlyCollection<DockPanel> DockPanelAllCollection { get { return _dockPanelAll.AsReadOnly(); } }
        /// <summary>返回左侧停靠方向的 ICollection&lt;DockPanel&gt; 只读集合</summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]
        public ReadOnlyCollection<DockPanel> DockPanelLeftCollection { get { return _dockPanelLeft.AsReadOnly(); } }
        /// <summary>返回右侧停靠方向的 ICollection&lt;DockPanel&gt; 只读集合</summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]
        public ReadOnlyCollection<DockPanel> DockPanelRightCollection { get { return _dockPanelRight.AsReadOnly(); } }
        /// <summary>返回顶部停靠方向的 ICollection&lt;DockPanel&gt; 只读集合</summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]
        public ReadOnlyCollection<DockPanel> DockPanelTopCollection { get { return _dockPanelTop.AsReadOnly(); } }
        /// <summary>返回底部停靠方向的 ICollection&lt;DockPanel&gt; 只读集合</summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]
        public ReadOnlyCollection<DockPanel> DockPanelBottomCollection { get { return _dockPanelBottom.AsReadOnly(); } }

        public event NavBarGroupEventHandler ActiveGroupChanged;
        public DockManagerExt() : base() { }
        public DockManagerExt(IContainer container) : base(container) { }
        public DockManagerExt(ContainerControl form) : base(form) { }
        /// <summary>将指定 DockPanel 注册到 DockManager</summary>
        /// <param name="dPanel"></param>
        /// <param name="defaultPosition">停靠方向 Left|Right|Top|Bottom </param>
        public void RegistDockPanel(DockPanelExt dPanel, string defaultPosition)
        {
            _dockPanelAll.Add(dPanel);
            dPanel.Register(this);

            switch (defaultPosition)
            {
                case "Left":
                    RegistDockPanelAtPositon(_dockPanelLeft, dPanel, "Left");
                    break;
                case "Right":
                    RegistDockPanelAtPositon(_dockPanelRight, dPanel, "Right");
                    break;
                case "Top":
                    RegistDockPanelAtPositon(_dockPanelTop, dPanel, "Top");
                    break;
                case "Bottom":
                    RegistDockPanelAtPositon(_dockPanelBottom, dPanel, "Bottom");
                    break;
                default:
                    throw new Exception("defaultPosition is not invalid.");
            }

            dPanel.ActiveGroupChanged += (sender, e) => { ActiveGroupChanged?.Invoke(sender, e); };
            dPanel.ClosingPanel += (sender, e) =>
            {
                _dockPanelAll.Remove(sender as DockPanel);

                Remove(_dockPanelLeft, sender as DockPanel, "Left");
                Remove(_dockPanelRight, sender as DockPanel, "Right");
                Remove(_dockPanelTop, sender as DockPanel, "Top");
                Remove(_dockPanelBottom, sender as DockPanel, "Bottom");
            };
        }
        void Remove(List<DockPanel> source, DockPanel dockPanel, string defaultPosition)
        {
            source.Remove(dockPanel);

            if (source.Count == 0)
            {
                _dockPanelExt[defaultPosition] = null;
            }
            else
            {
                if (_dockPanelExt[defaultPosition] == dockPanel) { _dockPanelExt[defaultPosition] = source[0]; }
            }
        }
        /// <summary>按特定停靠方式注册DockPanel</summary>
        void RegistDockPanelAtPositon(List<DockPanel> panelList, DockPanelExt dPanel, string defaultPosition)
        {
            panelList.Add(dPanel);
            if (_dockPanelExt[defaultPosition] == null)
            {
                dPanel.DockTo(GetDockingStyle(defaultPosition));
                _dockPanelExt[defaultPosition] = dPanel;
            }
            else { dPanel.DockAsTab(_dockPanelExt[defaultPosition]); }
        }

        DockingStyle GetDockingStyle(string defaultPosition)
        {
            switch (defaultPosition)
            {
                case "Left":
                    return DockingStyle.Left;
                case "Right":
                    return DockingStyle.Right;
                case "Top":
                    return DockingStyle.Top;
                case "Bottom":
                    return DockingStyle.Bottom;
                default:
                    return DockingStyle.Left;
            }
        }

        public void InitEvent()
        {
            this.ActiveGroupChanged += (sender, e) =>
            {
                NavBarGroupExt nbge = e.Group as NavBarGroupExt;
                if (nbge != null)
                {
                    if (nbge.TreeList != null)
                    {
                        TreeListExt.UpdateText(nbge.TreeList.Nodes);
                    }
                    else if (nbge.TreeView != null)
                    {
                        TreeViewExt.UpdateText(nbge.TreeView.Nodes);
                    }
                }
            };
            this.ActiveChildChanged += (sender, e) =>
            {
                if (e.Panel != null && e.Panel.ActiveChild != null)
                {
                    UpdateText(e.Panel.ActiveChild as DockPanelExt);
                }
            };
            this.VisibilityChanged += (sender, e) =>
            {
                if (e.Visibility == DockVisibility.Visible)
                {
                    UpdateText(e.Panel as DockPanelExt);
                }
            };
        }

        static void UpdateText(DockPanelExt dPanelExt)
        {
            if (dPanelExt != null)
            {
                LoggingService.DebugFormatted("UpdateText ActiveDockPanelExt  1");
                foreach (NavBarGroupExt nbge in dPanelExt.Groups)
                {
                    nbge.UpdateText();
                }
                if (dPanelExt.ActiveTreeView != null)
                { TreeViewExt.UpdateText(dPanelExt.ActiveTreeView.Nodes); }
                else if (dPanelExt.ActiveTreeList != null)
                { TreeListExt.UpdateText(dPanelExt.ActiveTreeList.Nodes); }

                LoggingService.DebugFormatted("UpdateText ActiveDockPanelExt  2");
            }
        }

        public void UpdateText()
        {
            foreach (DockPanel dPanel in DockPanelAllCollection)
            {
                if (dPanel is DockPanelExt)
                {
                    (dPanel as DockPanelExt).UpdateText();
                }
            }
            foreach (DockPanel dPanel in RootPanels)
            {//更新当前显示的DockPanel及其内部控件
                if (dPanel.Count > 0) { UpdateText(dPanel.ActiveChild as DockPanelExt); }
                else { UpdateText(dPanel as DockPanelExt); }
            }
        }
    }
}
